package com.kede.pay.config;

import com.wechat.pay.java.core.auth.Validator;
import com.wechat.pay.java.core.cipher.Verifier;
import com.wechat.pay.java.core.http.HttpHeaders;
import lombok.extern.slf4j.Slf4j;

import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;

import static java.util.Objects.requireNonNull;

/**
 * @Author:Pr.li
 * @Date: create in 2023/6/28 21:22
 */
@Slf4j
public class MyWechatPay2Validator implements Validator {


    public static final String AUTHORIZATION = "authorization";
    public static final String REQUEST_ID = "request-id";
    public static final String WECHAT_PAY_SERIAL = "wechatpay-serial";
    public static final String WECHAT_PAY_SIGNATURE = "wechatpay-signature";
    public static final String WECHAT_PAY_TIMESTAMP = "wechatpay-timestamp";
    public static final String WECHAT_PAY_NONCE = "wechatpay-nonce";
    public static final String USER_AGENT = "user-agent";
    public static final String ACCEPT = "accept";
    public static final String CONTENT_TYPE = "content-type";

    private static final int RESPONSE_EXPIRED_MINUTES = 5;
    private final Verifier verifier;

    public MyWechatPay2Validator(Verifier verifier) {
        this.verifier = requireNonNull(verifier);
    }

    @Override
    public <T> boolean validate(HttpHeaders responseHeaders, String responseBody) {
        String timestamp = responseHeaders.getHeader(WECHAT_PAY_TIMESTAMP);
        try {
            Instant responseTime = Instant.ofEpochSecond(Long.parseLong(timestamp));
            // 拒绝过期请求
            if (Duration.between(responseTime, Instant.now()).abs().toMinutes()
                    >= RESPONSE_EXPIRED_MINUTES) {
                throw new IllegalArgumentException(
                        String.format(
                                "Validate http response,timestamp[%s] of httpResponse is expires, "
                                        + "request-id[%s]",
                                timestamp, responseHeaders.getHeader(REQUEST_ID)));
            }
        } catch (DateTimeException | NumberFormatException e) {
            throw new IllegalArgumentException(
                    String.format(
                            "Validate http response,timestamp[%s] of httpResponse is invalid, request-id[%s]",
                            timestamp, responseHeaders.getHeader(REQUEST_ID)));
        }
        String message =
                timestamp
                        + "\n"
                        + responseHeaders.getHeader(WECHAT_PAY_NONCE)
                        + "\n"
                        + (responseBody == null ? "" : responseBody)
                        + "\n";
        log.debug("Message for verifying signatures is[{}]", message);
        String serialNumber = responseHeaders.getHeader(WECHAT_PAY_SERIAL);
        log.debug("SerialNumber for verifying signatures is[{}]", serialNumber);
        String signature = responseHeaders.getHeader(WECHAT_PAY_SIGNATURE);
        log.debug("Signature for verifying signatures is[{}]", signature);
        return verifier.verify(serialNumber, message, signature);
    }
}
